<template>
  <el-dialog
    v-model="visible"
    :title="dialogTitle"
    :width="width"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      :label-width="labelWidth"
      :label-position="labelPosition"
    >
      <slot :form-data="formData" :is-edit="isEdit" />
    </el-form>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button
          type="primary"
          :loading="loading"
          @click="handleSubmit"
        >
          {{ isEdit ? '更新' : '创建' }}
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'

interface Props {
  modelValue: boolean
  title?: string
  editTitle?: string
  createTitle?: string
  width?: string
  labelWidth?: string
  labelPosition?: 'left' | 'right' | 'top'
  formData: Record<string, any>
  rules?: FormRules
  loading?: boolean
  isEdit?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  title: '',
  editTitle: '编辑',
  createTitle: '新增',
  width: '600px',
  labelWidth: '100px',
  labelPosition: 'right',
  loading: false,
  isEdit: false
})

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  submit: [formData: Record<string, any>]
  cancel: []
  close: []
}>()

// 响应式数据
const formRef = ref<FormInstance>()
const visible = ref(props.modelValue)

// 计算属性
const dialogTitle = computed(() => {
  if (props.title) return props.title
  return props.isEdit ? props.editTitle : props.createTitle
})

// 监听器
watch(
  () => props.modelValue,
  (newValue) => {
    visible.value = newValue
    if (newValue) {
      // 对话框打开时，重置表单验证状态
      nextTick(() => {
        formRef.value?.clearValidate()
      })
    }
  }
)

watch(visible, (newValue) => {
  emit('update:modelValue', newValue)
})

// 事件处理
const handleSubmit = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    emit('submit', props.formData)
  } catch (error) {
    console.log('表单验证失败:', error)
  }
}

const handleCancel = () => {
  visible.value = false
  emit('cancel')
}

const handleClose = () => {
  emit('close')
}

// 暴露方法
const resetFields = () => {
  formRef.value?.resetFields()
}

const clearValidate = () => {
  formRef.value?.clearValidate()
}

const validate = () => {
  return formRef.value?.validate()
}

defineExpose({
  resetFields,
  clearValidate,
  validate
})
</script>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

:deep(.el-dialog__header) {
  padding: 20px 20px 10px;
  border-bottom: 1px solid var(--el-border-color-light);
}

:deep(.el-dialog__body) {
  padding: 20px;
  max-height: 60vh;
  overflow-y: auto;
}

:deep(.el-dialog__footer) {
  padding: 10px 20px 20px;
  border-top: 1px solid var(--el-border-color-light);
}

:deep(.el-form-item) {
  margin-bottom: 20px;
}

:deep(.el-form-item__label) {
  font-weight: 500;
  color: var(--el-text-color-primary);
}

:deep(.el-input),
:deep(.el-select),
:deep(.el-textarea) {
  width: 100%;
}
</style>
